/*package com.smarttest.portal.service.timertask;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.chinaway.gps.model.GpsCard;
import com.chinaway.gps.model.Location;
import com.smarttest.portal.refresh.gps.dao.LctTraceDao;
import com.smarttest.portal.refresh.gps.manager.GpsCardManager;
import com.smarttest.portal.refresh.gpsevent.dao.RangeEventDao;
import com.smarttest.portal.refresh.gpsevent.dao.convert.EventConstants;
import com.smarttest.portal.refresh.gpsevent.hanlder.impl.RangeMonitorHandler;
import com.smarttest.portal.refresh.gpsevent.manager.RangeManager;
import com.smarttest.portal.refresh.util.model.RangeEventConstant;
import com.smarttest.portal.service.RangeStopCountService;

@Service
public class RangeRefreshMonitor {
	private final ConcurrentHashMap<Integer, AtomicInteger> metrics = new ConcurrentHashMap<Integer, AtomicInteger>();
	private final Logger logger = LoggerFactory.getLogger(getClass());
	private Date startTime;
	private Date endTime;
//	private String imei;
//	private String orgcode;
	private int batchSize = 30;
	public static boolean REFRESH_RANGE = true;
	// public static boolean REFRESH_STOP = false;
	// public static boolean REFRESH_SPEED = false;
	@Value("${orgCodes}")
	private String orgCodes;
//	private static String[] orgCodes = { "20008D", "2004BV", "20087I",
//			"200F5Z", "100018", "200JLK", "200J90", "200IOI", "200OQX" };
//	private static String[] orgCodes = { "200HF7" };

	private ThreadPoolExecutor threadPool;

	@Resource
	private List<RangeMonitorHandler> handlers;
	@Resource
	private GpsCardManager cardManager;
	@Resource
	private RangeManager rangeManager;
	@Resource
	private LctTraceDao lctTraceDao;
	@Resource
	private RangeEventDao rangeEventDao;
	@Autowired
	RangeStopCountService rangeStopCountService;

	public JSONObject getAllRangeEvent(Date startTime, Date endTime) {
		this.startTime=startTime;
		this.endTime=endTime;
		JSONObject json = new JSONObject();
		initThreadPool();
		ConcurrentHashMap<Integer, AtomicInteger> map = process();
		stop();
		int RangeInBefore = map.get(RangeEventConstant.range_In_Bef).intValue();
		int RangeOutBefore = map.get(RangeEventConstant.range_Out_Bef).intValue();
		int RangeInAfter = map.get(RangeEventConstant.range_In_Af).intValue();
		int RangeOutAfter = map.get(RangeEventConstant.range_Out_Af).intValue();
		json.put("RangeInBefore", RangeInBefore);
		json.put("RangeOutBefore", RangeOutBefore);
		json.put("RangeInAfter", RangeInAfter);
		json.put("RangeOutAfter", RangeOutAfter);
		json.put("RangeBefore", RangeInBefore+RangeOutBefore);
		json.put("RangeAfter", RangeInAfter+RangeOutAfter);

		return json;
	}

	private void initThreadPool() {
		threadPool = new ThreadPoolExecutor(50, 50, 300L, TimeUnit.SECONDS,
				new LinkedBlockingQueue<Runnable>(50));
		threadPool.setRejectedExecutionHandler(new CallerRunsPolicy());
		
	}


	private ConcurrentHashMap<Integer, AtomicInteger> process() {
		long start = System.currentTimeMillis();
		logger.info("进出区域开始初始化......");
		logger.info(
				"进出区域刷新参数：本次刷新事件:RANGE:{},刷新区域:START:{},END:{}",
				 REFRESH_RANGE, startTime, endTime);

		String[] orgcodeArr = StringUtils.split(orgCodes, ",");
		Map<String, GpsCard> cardMap = new HashMap<String, GpsCard>();
		for(String orgcode : orgcodeArr){
			Map<String, GpsCard> map = cardManager.findByOrgcode(orgcode);
			cardMap.putAll(map);
			logger.info("开始初始化GPSCARD,通过ORGCODE:{}", orgcode);
		}
		
		
		logger.info("初始化GPSCARD完成.需要刷新的设备数 ：{}", cardMap.size());
		if (cardMap.size() == 0) {
			logger.info("没有需要刷新的设备 scope");
			System.exit(0);
		}

		logger.info("===============================");

		final LinkedBlockingQueue<GpsCard> queue = new LinkedBlockingQueue<GpsCard>();
		queue.addAll(cardMap.values());
		final CountDownLatch cd = new CountDownLatch(batchSize);
		metrics.put(RangeEventConstant.range_In_Bef, new AtomicInteger(0));
		metrics.put(RangeEventConstant.range_Out_Bef, new AtomicInteger(0));
		metrics.put(RangeEventConstant.range_In_Af, new AtomicInteger(0));
		metrics.put(RangeEventConstant.range_Out_Af, new AtomicInteger(0));
		final AtomicInteger count = new AtomicInteger();
		for (int i = 0; i < batchSize; i++) {
			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						while (true) {
							GpsCard card = queue.poll(10, TimeUnit.SECONDS);
							if (card == null) {
								logger.info("线程10秒内未能获取到数据;自行消亡");
								return;
							}
							//
							long start = System.currentTimeMillis();
							HashMap<Integer, Integer> countMap = scanDevices(card);
							int countAddIn = metrics.get(RangeEventConstant.range_In_Af)
									.addAndGet(countMap.get(RangeEventConstant.range_In_Af));
							int countAddOut = metrics.get(RangeEventConstant.range_Out_Af)
									.addAndGet(countMap.get(RangeEventConstant.range_Out_Af));
							int countIn = metrics.get(RangeEventConstant.range_In_Bef)
									.addAndGet(
											countMap.get(RangeEventConstant.range_In_Bef));
							int countOut = metrics
									.get(RangeEventConstant.range_Out_Bef)
									.addAndGet(
											countMap.get(RangeEventConstant.range_Out_Bef));

							// int countIn =
							// metrics.get(RangeEvent.TP_IN).addAndGet(1);
							// int countOut =
							// metrics.get(RangeEvent.TP_OUT).addAndGet(2);
							metrics.put(RangeEventConstant.range_In_Af, new AtomicInteger(
									countAddIn));
							metrics.put(RangeEventConstant.range_Out_Af, new AtomicInteger(
									countAddOut));
							metrics.put(RangeEventConstant.range_In_Bef,
									new AtomicInteger(countIn));
							metrics.put(RangeEventConstant.range_Out_Bef,
									new AtomicInteger(countOut));
							int nowCount = count.addAndGet(1);
//							if(nowCount%3==2){
							if(nowCount%500==499){
								saveDB(metrics);
							}
							logger.info("{},刷新完成设备：{},耗时:{}", nowCount,card.getGpsid(),
									System.currentTimeMillis() - start);
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						cd.countDown();
					}
				}

				private void saveDB(ConcurrentHashMap<Integer, AtomicInteger> metrics) {
					int rangeInBefore = metrics.get(RangeEventConstant.range_In_Bef).intValue();
					int rangeOutBefore = metrics.get(RangeEventConstant.range_Out_Bef).intValue();
					int rangeInAfter = metrics.get(RangeEventConstant.range_In_Af).intValue();
					int rangeOutAfter = metrics.get(RangeEventConstant.range_Out_Af).intValue();
					Date dbStart = new Date();
					dbStart.setHours(0);
					dbStart.setMinutes(0);
					dbStart.setSeconds(0);
					
					Date dbEnd = new Date();
					dbEnd.setHours(23);
					dbEnd.setMinutes(59);
					dbEnd.setSeconds(59);
					
					rangeStopCountService.saveEvent(10, rangeInBefore, rangeInAfter,dbStart,dbEnd);
					rangeStopCountService.saveEvent(11, rangeOutBefore, rangeOutAfter,dbStart,dbEnd);
				}
			});
		}

		try {
			cd.await();
			long end = System.currentTimeMillis();
			logger.info("进出区域刷新完成===耗时："+(end-start));
			return metrics;
			// System.exit(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return metrics;
	}
	public static void main(String[] args) {
		for (int nowCount = 0; nowCount < 12000; nowCount++) {
			if(nowCount%500==499){
				System.out.println(nowCount);
			}
		}
	}

	private HashMap<Integer, Integer> scanDevices(GpsCard card) {
//		card.setGpsid("106014000111618");
		
		HashMap<Integer, Integer> countMap = new HashMap<Integer, Integer>();
		countMap.put(RangeEventConstant.range_In_Af, 0);
		countMap.put(RangeEventConstant.range_Out_Af, 0);
		
		long start = System.currentTimeMillis();
		String imei = card.getGpsid();
		int in = rangeEventDao.countEvent(imei, startTime, endTime, EventConstants.GpsEventType.RANG_IN.getIndex());
		int out = rangeEventDao.countEvent(imei, startTime, endTime, EventConstants.GpsEventType.RANGE_OUT.getIndex());
		// 暂时先这样写
		countMap.put(RangeEventConstant.range_In_Bef, in);
		countMap.put(RangeEventConstant.range_Out_Bef,out);
		Date from = startTime;
//		while (from.getTime() < endTime.getTime()) {
			List<Location> lcts = new ArrayList<Location>();
			try {
				lcts = lctTraceDao.findByList(card.getGpsid(), from, endTime);
				if (lcts == null || lcts.size() == 0) {
					logger.info("该时间段无定位数据 imei={}", imei);
					return countMap;
				}
			} catch (Exception e) {
				logger.info("获取定位数据失败 imei={}", imei, e);
				return countMap;
			}

			for (RangeMonitorHandler handler : handlers) {
				try {
					// countMap：countMap.put(RangeEvent.TP_IN/OUT, addIn/Out);
					HashMap<Integer, Integer> map = handler.refreshCount(card, lcts, from, endTime);
					int countIn = map.get(RangeEventConstant.range_In_Af)+countMap.get(RangeEventConstant.range_In_Af);
					int countOut = map.get(RangeEventConstant.range_Out_Af)+countMap.get(RangeEventConstant.range_Out_Af);
					countMap.put(RangeEventConstant.range_In_Af, countIn);
					countMap.put(RangeEventConstant.range_Out_Af, countOut);
				} catch (Exception e) {
					logger.info("刷新事件失败 imei={}, class={}", imei,
							handler.getClass());
				}
			}
			
			//逐步向endTime靠近进行刷新
//			from = lcts.get(lcts.size() - 1).getTime();
//			if (lcts.size() < 1000) {
				//如果轨迹点小于1000个就不再执行
//				break;
//			}
//		}
		long time = System.currentTimeMillis() - start;
		return countMap;
	}

	private void stop() {
		threadPool.shutdown();
	}
}
*/